#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#define min(m, n) ((m) < (n) ? (m) : (n))
#define max(m, n) ((m) > (n) ? (m) : (n))

#define IPV4_LEN sizeof(struct sockaddr_in)
#define ERR_EXIT(m)         \
    do                      \
    {                       \
        perror(m);          \
        exit(EXIT_FAILURE); \
    } while (0)

/* Set struct sockaddr_in */
struct sockaddr_in set_addr(const char *ip, uint16_t port)
{
    struct sockaddr_in addr;

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    if (inet_pton(AF_INET, ip, (void *)&addr.sin_addr) == -1)
    {
        ERR_EXIT("inet_pton()");
    }
    bzero(&addr.sin_zero, 8);

    return addr;
}

int get_sock(struct sockaddr_in *addr)
{
    int socket_fd;

    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd == -1)
    {
        ERR_EXIT("socket()");
    }

    if (bind(socket_fd, (struct sockaddr *)addr, IPV4_LEN) == -1)
    {
        ERR_EXIT("bind()");
    }

    return socket_fd;
}

void get_rand_fname(char *filename, int max_length)
{
    time_t current_time;
    struct tm *time_info;
    char buffer[max_length];

    time(&current_time);
    time_info = localtime(&current_time);
    strftime(buffer, max_length, "%Y%m%d%H%M%S", time_info);
    snprintf(filename, max_length, "%s_%d", buffer, rand());
}